#include "Dumper.h"

Dumper::Dumper() :
    m_layer_list(*(Layer_List::get_instance()))
{

}

Dumper::~Dumper()
{

}

void Dumper::dump_image_list(MAP_IMAGE &mymaplist)
{
    outConstants << endl << "enum auto_image {" << endl;
    ImageList &img = *(ImageList::get_instance());
    MAP_IMAGE::iterator itrImage;
    int imageCount = 0;
    string lastImageId;
    out << "//Images" << endl;
	for(itrImage = mymaplist.begin(); itrImage != mymaplist.end(); itrImage++)
	{
	    ++imageCount;
	    ImageListItem &image = img[(*itrImage).first];
	    outConstants << image.m_id << "," <<  endl;
		out << "images[" << image.m_id << "] = new Image_Wrapper(\"" << image.m_pImg->get_path() << "\");" << endl;
        lastImageId = image.m_id;
	}
    outConstants << "AUTO_IMAGES_MAX = " << lastImageId <<  endl << "};" << endl;
//    outConstants << "#define\tIMAGE_COUNT\t" << imageCount << endl;
}

void Dumper::dump_sprite_list(MAP_IMAGE &mymaplist)
{
    outConstants << endl << "enum auto_sprites {" << endl;
    ImageList &img = *(ImageList::get_instance());
    MAP_IMAGE::iterator itrImage;
    int spriteCount = 0;
    string lastSpriteId;

    out << "//Sprites" << endl;
	for(itrImage = mymaplist.begin(); itrImage != mymaplist.end(); itrImage++)
	{
	    ImageListItem &image = img[(*itrImage).first];
		VECTOR_SPRITES::iterator itrSprite;
		for(itrSprite = (*itrImage).second.begin(); itrSprite != (*itrImage).second.end(); itrSprite++)
		{
		    ++spriteCount;
		    lastSpriteId = image.m_spriteList[(*itrSprite)].m_id;
		    outConstants << image.m_spriteList[(*itrSprite)].m_id << "," << endl;
			out << "sprites[" << lastSpriteId << "] = new Sprite("
			<< image.m_id << ", " <<
			image.m_spriteList[(*itrSprite)].m_rect.x << ", " <<
			image.m_spriteList[(*itrSprite)].m_rect.y << ", " <<
			image.m_spriteList[(*itrSprite)].m_rect.w << ", " <<
			image.m_spriteList[(*itrSprite)].m_rect.h << ");" << endl;
		}
		(*itrImage).second.clear();
	}
	outConstants << "AUTO_SPRITES_MAX = " << lastSpriteId <<  endl << "};" << endl;
//    outConstants << "#define\tSPRITE_COUNT\t" << spriteCount << endl;
}

void Dumper::collect_and_dump()
{
    cout << "Dumper::collect_and_dump()" << endl;
    ImageList &img = *(ImageList::get_instance());
    MAP_IMAGE mylist;
    int spriteinstanceCounter = 0;
    int layercounter = 0;
    int maxX = 0, maxY = 0;
    int minX = 0, minY = 0;
    out.open("out.txt");
    outConstants.open("constants.txt");
    m_layer_list.lock();
    list<Layer *>::iterator begin, end = m_layer_list.getListIteratorEnd();

    for (begin = m_layer_list.getListIteratorBegin(); begin != end; begin++) {
         int layerSpriteCount = 0;
         if (!(*begin)->isVisible()) {
             continue;
         }
         out << "//layer" << (*begin)->getLayerId() << endl;
         outConstants << "#define\tLAYER_" << layercounter++ << "_SPRITE_INDEX_START\t" << spriteinstanceCounter << endl;
         list<SpriteInstance>::iterator b, e = (*begin)->getspriteInstanceListIteratorEnd();

         for (b = (*begin)->getspriteInstanceListIteratorBegin(); b != e; b++) {
             ImageListItem &image = img[(*b).m_imgId];

             insert(mylist, (*b).m_imgId, (*b).m_spriteId);
             out << "initInstance(" << spriteinstanceCounter++ << ", " << image.m_id << ", " << image.m_spriteList[(*b).m_spriteId].m_id << ", " <<
             (*b).m_posRect.m_rect.x << ", " << (*b).m_posRect.m_rect.y << ", " << (*b).m_posRect.m_x2 << ", " << (*b).m_posRect.m_y2 << ", " <<
             (*b).m_visible << ", " << (*b).m_solid << ");" << endl;
             ++layerSpriteCount;

             int tmp = (*b).m_posRect.m_rect.x;
             if(tmp < minX) {
                 minX = tmp;
             }
			 tmp = (*b).m_posRect.m_x2;
			 if(tmp > maxX) {
			    maxX = tmp;
             }

             tmp = (*b).m_posRect.m_rect.y;
             if(tmp < minY) {
                 minY = tmp;
             }
			 tmp = (*b).m_posRect.m_y2;
			 if(tmp > maxY) {
			    maxY = tmp;
             }
         }
         outConstants << "#define LAYER_" << layercounter - 1 << "_SPRITE_COUNT\t" << layerSpriteCount << endl;
    }

    outConstants << "#define\tLAYER_COUNT\t" << layercounter << endl;
    outConstants << "#define\tSPRITE_INSTANCE_COUNT\t" << spriteinstanceCounter << endl;
    outConstants << "#define\tSPACEXMAX\t" << maxX << endl;
    outConstants << "#define\tSPACEYMAX\t" << maxY << endl;
    outConstants << "#define\tSPACEXMIN\t" << minX << endl;
    outConstants << "#define\tSPACEYMIN\t" << minY << endl;
    out << "==end==" << endl;
    out.close();
    out.open("out1.txt");
    dump_image_list(mylist);
    dump_sprite_list(mylist);
    outConstants.close();
    out.close();
    m_layer_list.unlock();
    mylist.clear();
}

void Dumper::insert(MAP_IMAGE &mymaplist, const int imageId, int spriteId)
{
    ImageList &img = *(ImageList::get_instance());
    ImageListItem &image = img[imageId];

    cout << "insert" << imageId << " " << img[imageId].m_id << " " << spriteId <<  " " << image.m_spriteList[spriteId].m_id << " "
    << image.m_spriteList[spriteId].m_rect.x << " " << image.m_spriteList[spriteId].m_rect.y << endl;

	MAP_IMAGE::iterator itrImage = mymaplist.find(imageId);
	if (itrImage == mymaplist.end()) {
		mymaplist.insert(PAIR_IMAGE(imageId, VECTOR_SPRITES()));
	}

	VECTOR_SPRITES &sprites = mymaplist[imageId];

	for(VECTOR_SPRITES::iterator itrSprite = sprites.begin(); itrSprite != sprites.end(); itrSprite++) {
	    if(*itrSprite == spriteId) {
	        return;
	    }
	}
	sprites.push_back(spriteId);
}
